﻿using Gym.Application.Common.Interfaces;
using Gym.Domain.Common;
using Gym.Domain.SessionAggregate.Events;
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Throw;

namespace Gym.Application.Participants.Events
{
    public class SessionSpotReservedEventHandler : INotificationHandler<SessionSpotReservedEvent>
    {
        private readonly IParticipantsRepository _participantsRepository;

        public SessionSpotReservedEventHandler(IParticipantsRepository participantsRepository)
        {
            _participantsRepository = participantsRepository;
        }

        public async Task Handle(SessionSpotReservedEvent notification, CancellationToken cancellationToken)
        {
            var participant = await _participantsRepository.GetByIdAsync(notification.Reservation.ParticipantId);
            participant.ThrowIfNull();

            var result = participant.AddToSchedule(notification.Session);

            if(result.IsError)
            {
                throw new EventualConsistencyException(
                    SessionSpotReservedEvent.ParticipantScheduleUpdateFailed,
                result.Errors);
            }

            await _participantsRepository.UpdateAsync(participant);
        }
    }
}
